package com.hcj.util.jpushUtil;

import java.net.URI;
import java.net.URISyntaxException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.ServiceHelper;
import cn.jiguang.common.connection.NettyHttpClient;
import cn.jiguang.common.resp.ResponseWrapper;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import io.netty.handler.codec.http.HttpMethod;

public class JpushUtil {

    private final static String APP_KEY = "53e5f0f211d2b4fd5b7df3f4";

    private final static String MASTER_SECRET = "43e45d4c251c2a5d900060b1";
    protected static final Logger LOG = LoggerFactory.getLogger(JpushUtil.class);


    /**
     * 向所有设备发送消息
     * @param title
     * @param content
     * @return
     */
    private static PushPayload buildPushObject_all_msg(String title,String content) {
    	return PushPayload.newBuilder().setPlatform(Platform.all()).setAudience(Audience.all())
    			.setMessage(Message.newBuilder().setTitle(title).setMsgContent(content).build())
    			.setOptions(Options.newBuilder()
                        //此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
                        .setApnsProduction(false)
                        //此字段是给开发者自己给推送编号，方便推送者分辨推送记录
                        .setSendno(1)
                        //此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
                        .setTimeToLive(864000)//10天
                        .build())
    			.build();
    }
    /**
     * 向所有设备同时发送通知和消息
     * @param message
     * @param title
     * @param content
     * @return
     */
    private static PushPayload buildPushObject_all_alertAndMsg(String message,String title,String content) {
    	return PushPayload.newBuilder().setPlatform(Platform.all()).setAudience(Audience.all())
    			.setNotification(Notification.newBuilder().setAlert(message).build())
    			.setMessage(Message.newBuilder().setContentType("UTF-8").setTitle(title).setMsgContent(content).addExtra("poid", "poid_123456").addExtra("poname", "poname_123456").build())
    			.setOptions(Options.newBuilder()
                        //此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
                        .setApnsProduction(false)
                        //此字段是给开发者自己给推送编号，方便推送者分辨推送记录
                        .setSendno(1)
                        //.setSendno("815c2802cff34d7292204d7af532aa45")
                        //此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
                        .setTimeToLive(864000)//10天
                        .build())
    			.build();
    }
    
    public static void sendMsgAll(String title,String content) {
    	ClientConfig clientConfig = ClientConfig.getInstance();
    	String host = (String) clientConfig.get(ClientConfig.PUSH_HOST_NAME);
    	final NettyHttpClient client = new NettyHttpClient(ServiceHelper.getBasicAuthorization(APP_KEY, MASTER_SECRET),
    			null, clientConfig);
    	try {
    		URI uri = new URI(host + clientConfig.get(ClientConfig.PUSH_PATH));
    		PushPayload payload = buildPushObject_all_msg(title, content);
    		client.sendRequest(HttpMethod.POST, payload.toString(), uri, new NettyHttpClient.BaseCallback() {
    			@Override
    			public void onSucceed(ResponseWrapper responseWrapper) {
//                    LOG.info("Got resultUtil: " + responseWrapper.responseContent);
    			}
    		});
    		client.close();
    	} catch (URISyntaxException e) {
    		e.printStackTrace();
    	}
    }
    public static void sendAlertAndMsgAll(String message,String title,String content) {
    	ClientConfig clientConfig = ClientConfig.getInstance();
    	String host = (String) clientConfig.get(ClientConfig.PUSH_HOST_NAME);
    	final NettyHttpClient client = new NettyHttpClient(ServiceHelper.getBasicAuthorization(APP_KEY, MASTER_SECRET),
    			null, clientConfig);
    	try {
    		URI uri = new URI(host + clientConfig.get(ClientConfig.PUSH_PATH));
    		PushPayload payload = buildPushObject_all_alertAndMsg(message, title, content);
    		client.sendRequest(HttpMethod.POST, payload.toString(), uri, new NettyHttpClient.BaseCallback() {
    			@Override
    			public void onSucceed(ResponseWrapper responseWrapper) {
//                    LOG.info("Got resultUtil: " + responseWrapper.responseContent);
    			}
    		});
    		client.close();
    	} catch (URISyntaxException e) {
    		e.printStackTrace();
    	}
    }
    // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // 下面是测试好的接口，都是发通知类消息
    /**
     * 向所有设备的特定用户发送通知
     * @param content 的内容 message
     * @param  alias 约定为userid
     * @return
     */
    public static PushPayload buildPushObject_all_alert_withAlias(String content,String alias) {
    	System.out.println("buildPushObject_all_alert_withAlias"+"别名为："+alias);
        return PushPayload.newBuilder()
        		.setPlatform(Platform.all())
        		//.setAudience(Audience.all())
        		.setAudience(Audience.alias(alias))
        		.setNotification(Notification.newBuilder().setAlert(content).build())
        		//自定义消息
        		//.setMessage(Message.newBuilder().setContentType("UTF-8").setTitle("title").setMsgContent("msgContent").build())
    			.setMessage(Message.newBuilder().setContentType("UTF-8").setTitle("标题").setMsgContent(content).build())
        		.setOptions(Options.newBuilder()
                        //此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
                        //.setApnsProduction(true)
                        //此字段是给开发者自己给推送编号，方便推送者分辨推送记录
                        .setSendno(1)
                        //此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
                        .setTimeToLive(864000)//10天
                        .build())
    			.build();
    }
    /**
     * 向所有设备的特定用户发送通知
     * @param content 的内容 message
     * @param alias 约定为userid
     * @return
     */
    public static PushPayload buildPushObject_all_alert_withAlias(String content,String json, String alias) {
    	System.out.println("buildPushObject_all_alert_withAlias"+"别名为："+alias);
    	return PushPayload.newBuilder()
    			.setPlatform(Platform.ios())
    			//.setAudience(Audience.all())
    			.setAudience(Audience.alias(alias))
    			.setNotification(Notification.newBuilder().build())
    			//自定义消息
    			//.setMessage(Message.newBuilder().setContentType("UTF-8").setTitle("title").setMsgContent("msgContent").build())
    			.setMessage(Message.newBuilder().setContentType("UTF-8").setTitle("标题").setMsgContent(content).addExtra("jsonData", json).build())
    			.setOptions(Options.newBuilder()
    					//此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
    					//.setApnsProduction(true)
    					//此字段是给开发者自己给推送编号，方便推送者分辨推送记录
    					.setSendno(1)
    					//此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
    					.setTimeToLive(864000)//10天
    					.build())
    			.build();
    }
    
    /**
     * 向android设备的特定用户发送通知
     * @param message 的内容 message
     * @param alias 约定为userid
     * @return
     */
    public static PushPayload buildPushObject_android_alert_withAlias(String message, String alias) {
    	System.out.println("buildPushObject_android_alert_withAlias"+"别名为："+alias);
    	return PushPayload.newBuilder()
    			.setPlatform(Platform.android())
    			//.setAudience(Audience.all())
    			.setAudience(Audience.alias(alias))
    			.setNotification(Notification.newBuilder().setAlert(message).build())
    			.setOptions(Options.newBuilder()
    					//此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
    					//.setApnsProduction(true)
    					//此字段是给开发者自己给推送编号，方便推送者分辨推送记录
    					.setSendno(1)
    					//此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
    					.setTimeToLive(864000)//10天
    					.build())
    			.build();
    }
    
    /**
     * 向ios设备的特定用户发送通知
     * @param message 的内容 message
     * @param alias 约定为userid
     * @return
     */
    public static PushPayload buildPushObject_ios_alert_withAlias(String message, String alias) {
    	System.out.println("buildPushObject_ios_alert_withAlias"+"别名为："+alias);
    	return PushPayload.newBuilder()
    			.setPlatform(Platform.ios())
    			//.setAudience(Audience.all())
    			.setAudience(Audience.alias(alias))
    			.setNotification(Notification.newBuilder().setAlert(message).build())
    			.setOptions(Options.newBuilder()
    					//此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
    					//.setApnsProduction(true)
    					//此字段是给开发者自己给推送编号，方便推送者分辨推送记录
    					.setSendno(1)
    					//此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
    					.setTimeToLive(864000)//10天
    					.build())
    			.build();
    }
    
    /**
     * 向所有设备的用户发送通知
     * @param message
     * @return
     */
    public static PushPayload buildPushObject_all_alert(String message) {
    	System.out.println("buildPushObject_all_alert");
    	return PushPayload.newBuilder()
    			.setPlatform(Platform.all())
    			.setAudience(Audience.all())
    			.setNotification(Notification.newBuilder().setAlert(message).build())
    			.setOptions(Options.newBuilder()
    					//此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
    					.setApnsProduction(true)
    					//此字段是给开发者自己给推送编号，方便推送者分辨推送记录
    					.setSendno(1)
    					//此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
    					.setTimeToLive(864000)//10天
    					.build())
    			.build();
    }
    
    
    /**
     * 向Android设备的用户发送通知
     * @param message
     * @return
     */
    public static PushPayload buildPushObject_android_alert(String message) {
    	System.out.println("buildPushObject_android_alert");
    	return PushPayload.newBuilder()
    			.setPlatform(Platform.android())
    			.setAudience(Audience.all())
    			.setNotification(Notification.newBuilder().setAlert(message).build())
    			.setOptions(Options.newBuilder()
    					//此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
    					//.setApnsProduction(true)
    					//此字段是给开发者自己给推送编号，方便推送者分辨推送记录
    					.setSendno(1)
    					//此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
    					.setTimeToLive(864000)//10天
    					.build())
    			.build();
    }
    
    /**
     * 向IOS设备的用户发送通知
     * @param message
     * @return
     */
    public static PushPayload buildPushObject_ios_alert(String message) {
    	System.out.println("buildPushObject_ios_alert");
    	return PushPayload.newBuilder()
    			.setPlatform(Platform.ios())
    			.setAudience(Audience.all())
    			.setNotification(Notification.newBuilder().setAlert(message).build())
    			.setOptions(Options.newBuilder()
    					//此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
    					//.setApnsProduction(true)
    					//此字段是给开发者自己给推送编号，方便推送者分辨推送记录
    					.setSendno(1)
    					//此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
    					.setTimeToLive(864000)//10天
    					.build())
    			.build();
    }
    
    /**
     * 向所有设备异步发通知
     * @param message
     */
    /**
     * 向设备发送消息通知
     * @param payload 推送的类型，方法有下面这些
     *  JpushUtil.buildPushObject_all_alert("all发送广播");
    	JpushUtil.buildPushObject_android_alert("android发送广播");
    	JpushUtil.buildPushObject_ios_alert("ios发送广播"));
    	JpushUtil.buildPushObject_all_alert_withAlias("all发送通知","815c2802cff34d7292204d7af532aa45");
    	JpushUtil.buildPushObject_android_alert_withAlias("android发送通知","815c2802cff34d7292204d7af532aa45");
    	JpushUtil.buildPushObject_ios_alert_withAlias("ios发送通知","815c2802cff34d7292204d7af532aa45");

     */
    public static void sendAlert(PushPayload payload) {
    	ClientConfig clientConfig = ClientConfig.getInstance();
        String host = (String) clientConfig.get(ClientConfig.PUSH_HOST_NAME);
        final NettyHttpClient client = new NettyHttpClient(ServiceHelper.getBasicAuthorization(APP_KEY, MASTER_SECRET),
                null, clientConfig);
        try {
            URI uri = new URI(host + clientConfig.get(ClientConfig.PUSH_PATH));
            //PushPayload payload = buildPushObject_all_alert(message);
            client.sendRequest(HttpMethod.POST, payload.toString(), uri, new NettyHttpClient.BaseCallback() {
                @Override
                public void onSucceed(ResponseWrapper responseWrapper) {
                    LOG.info("Got resultUtil: " + responseWrapper.responseContent);
                }
            });
            client.close();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }
    
    
    
    /**
     * 这个是终极方法，适用于IOS和Android设备
     * @param content 发送内容
     * @param jsonStr 发送的字符串
     * @param userid  接收者的别名</br>
     * @return
     * audience	{"alias":["815c2802cff34d7292204d7af532aa45"]}</br>
     * notification	{"android":{"title":"Android Title","alert":"all发送通知"},"ios":{"sound":"","extras":{"extra_key":"{\"poname\":\"poname_1234567\",\"poid\":\"poid_1234567\"}"},"badge":"+1","alert":"all发送通知"},"alert":"all发送通知"}</br>
     * message	null</br>
     * options	{"sendno":1,"time_to_live":864000,"apns_production":false}</br>
     */
    public static PushPayload buildPushObject_android_and_ios(String content,String jsonStr,String userid) {
    	System.out.println("buildPushObject_android_and_ios"+"别名为："+userid+"\n jsonStr="+jsonStr+"\n 内容="+content);
    	return PushPayload.newBuilder()
                .setPlatform(Platform.android_ios())
                .setAudience(Audience.alias(userid))
                .setNotification(Notification.newBuilder()
                		.setAlert(content)
                		.addPlatformNotification(AndroidNotification.newBuilder()
                				.setTitle("通知")
                				.addExtra("extra_key", jsonStr)
                				.build())
                		.addPlatformNotification(IosNotification.newBuilder()
                				.incrBadge(1)
                				.addExtra("extra_key", jsonStr)
                				.build())
                		.build())
                // 这里是自定义消息，由于IOS获取不到message,所以不用
                //.setMessage(Message.newBuilder().setContentType("UTF-8").setTitle("标题").setMsgContent(content).addExtra("jsonData", json).build())
                .setOptions(Options.newBuilder()
    					//此字段的值是用来指定本推送要推送的apns环境，false表示开发，true表示生产；对android和自定义消息无意义
    					//.setApnsProduction(ture)
    					//此字段是给开发者自己给推送编号，方便推送者分辨推送记录
    					.setSendno(1)
    					//此字段的值是用来指定本推送的离线保存时长，如果不传此字段则默认保存一天，最多指定保留十天，单位为秒
    					.setTimeToLive(864000)//10天
    					.build())
                .build();
    }
    
    public static String jsonData(String poname,String poid){
    	JSONObject jo = new JSONObject();
    	jo.put("poid", poid == "" || poid == null ? "":poid);
    	jo.put("poname", poname == "" || poname == null ? "":poname);
    	return JSON.toJSONString(jo);
    }

    public static void main(String[] args){
    	//JpushUtil.sendAlert(JpushUtil.buildPushObject_all_alert("all发送广播"));
    	//JpushUtil.sendAlert(JpushUtil.buildPushObject_android_alert("android发送广播"));
    	//JpushUtil.sendAlert(JpushUtil.buildPushObject_ios_alert("ios发送广播"));
    	JSONObject jo = new JSONObject();
    	jo.put("poid", "5");
    	jo.put("poname", "news");
    	//JpushUtil.sendAlert(JpushUtil.buildPushObject_all_alert_withAlias("all发送通知",JSON.toJSONString(jo),"815c2802cff34d7292204d7af532aa45"));
    	// 910340163459170304 [王伟]
    	// 910385689124605952 [第祥]
    	JpushUtil.sendAlert(JpushUtil.buildPushObject_android_and_ios("这里是发送消息的内容",JSON.toJSONString(jo),"910340163459170304"));
    	//String jsonStr = "{\"poname\":\"poname_1234567\",\"poid\":\"poid_1234567\"}";
    	//jo = JSON.parseObject(jsonStr);
    	//System.out.println(jo.get("poname"));
    	//buildPushObject_all_alert_withAlias
    	//JpushUtil.sendAlert(JpushUtil.buildPushObject_android_alert_withAlias("android发送通知","815c2802cff34d7292204d7af532aa45"));
    	//JpushUtil.sendAlert(JpushUtil.buildPushObject_ios_alert_withAlias("ios发送通知","bbe717ffd1624034bab3fceee989f6c8"));
    	//JpushUtil.sendMsgAll("消息32","我的消息32");
    	//JpushUtil.sendAlertAndMsgAll("我的通知22", "我的消息22","我的通知消息22");
    }
}